/************

 Facebook manager
 refs:
 	- http://developers.facebook.com/docs/reference/plugins
	- http://developers.facebook.com/docs/reference/dialogs
	- http://fbdevwiki.com

 *************/

social.facebook.object = function ( id, access_token )
{
	var self = this;
	this.name = null;
	this.id = id;
	this.access_token = access_token;
	this.pages = [];

	this.cbacks = {
		'post': null
	};

	this.post = function ( message )
	{
		this._request ( 'feed', 'post', { message: message }, function ( res )
		{
			if ( self.cbacks [ 'post' ] ) self.cbacks [ 'post' ] ();
		} );
	};

	this.get_pages = function ( cback )
	{
		this.pages = [];
		this._request ( 'accounts', null, null, function ( res )
		{
			if ( res.data )
			{
				var i;
				for ( i in res.data )
				{
					var o = res.data [ i ];
					this.accounts.push ( new social.facebook.page ( o.id, o.access_token ) );
				}
				if ( cback ) cback ();
			}
		} );
	};

	this._request = function ( action, method, params, cback )
	{
		if ( params )
		{
			params [ 'access_token' ] = this.access_token;
			if ( method )
				FB.api ( '/' + this.id + '/' + action, method, params, cback );
			else
				FB.api ( '/' + this.id + '/' + action, params, cback );
		}
		else if ( action )
			FB.api ( '/' + this.id + '/' + action, cback );
	};
};

social.facebook.user = function ( id, access_token )
{
	var user = new social.facebook.object( id, access_token );
	
	user.status = null;
	user.uid = null;

	user.is_logged = function ()
	{
		return user.status == 'connected';
	};

	return user;
};

social.facebook.page = function ( id, access_token )
{
	var page = new social.facebook.object( id, access_token );

	return page;
};

social.facebook = new ( function ()
{
	var self = this;
	self._appid = null;
	self._status = null;
	self._access_token = null;
	self._accounts = null;
	self._uid = null;

	self.user = null;

	self.cbacks = {
		'init': null,
		'login': null,
		'logout': null,
		'feed': null,
		'post': null,
		'share': null,
		'publish': null
	};

	// INIT

	self.init = function ()
	{
		var root = document.createElement ( 'div' );
		root.id = 'fb-root';
		document.body.appendChild ( root );

		FB.init (
		{
			appId: self._appid,
			status: true,
			cookie: true,
			xfbml: true,
			oauth: true,
			frictionlessRequests: true
		} );
		FB.getLoginStatus ( self._login_status_cback );
	};

	// LOGIN / STATUS

	self._set_user = function ( s )
	{
		self.user = new social.facebook.user ( 'me', null );
		self.user.status = s.status;
		if ( s.authResponse )
		{
			self.user.access_token = s.authResponse.accessToken;
			self.user.uid = s.authResponse.userID;
		}
	};

	self._login_status_cback = function ( res )
	{
		console.debug ( 'fb login status cback: %o', res );
		
		self._set_user ( res );

		if ( self.user.is_logged () )
			self._load_me ( self.cbacks [ 'init' ] );
		else
			if ( self.cbacks [ 'init' ] ) self.cbacks [ 'init' ] ();

	};

	self._login_cback = function ( res )
	{
		console.debug ( 'fb login cback: %o', res );
		
		self._set_user ( res );

		if ( self.user.is_logged () )
			self._load_me ( self.cbacks [ 'login' ] );
		else
			if ( self.cbacks [ 'login' ] ) self.cbacks [ 'login' ] ();
	};

	self._load_me = function ( cback )
	{
		FB.api ( '/me', function ( res )
		{
			console.debug ( 'fb load me: %o', res );
			self.me = res;
			if ( cback ) cback ();
		} );
	};

	self._load_accounts = function ( cback )
	{
		FB.api ( '/me/accounts', function ( res )
		{
			console.debug ( 'fb load accounts: %o', res );
			self._accounts = res.data;
			if ( cback ) cback ();
		} );
	};

	self.login = function ()
	{
		if ( self.user.is_logged () )
		{
			self._load_me ( self.cbacks [ 'login' ] );
		}
		else
		{
			FB.login ( self._login_cback, { scope: 'email' } );
		}
	};

	self.logout = function ()
	{
		FB.logout ( self.cbacks [ 'logout' ] );
	};

	// LIWE LOGIN INTEGRATION

	self.user_login = function ( cback )
	{
		if ( self.is_logged () )
		{
			var params = {
				action : 'social.ajax.facebook_login',
				access_token : self._access_token
			};
			liwe.AJAX.easy ( params, function ( res )
			{
				if ( cback ) cback ( res );
			} );
			return true;
		}
		return false;
	};

	// LOGIN BUTTON TEMPLATE

	self.get_login = function ()
	{
		return String.formatDict ( social.templates [ 'facebook-login' ], { text: 'Login tramite Facebook' } );
	};

	// PERMISSIONS

	self.check_perm = function ( perm, cback )
	{
		FB.api ( '/me/permissions', function ( res )
		{
			console.debug ( 'fb check perm: %o', res );
			if ( ! res.error )
			{
				self._perms = res.data [ 0 ];
				if ( self._perms [ perm ] )
				{
					cback ();
					return;
				}
			}
			self.ask_perm ( perm, cback );
		} );
	};

	self.ask_perm = function ( perm, cback )
	{
		FB.ui ( 
		{
			method: 'permissions.request',
			display: 'popup', // HACK: to avoid conflict with object_enh
			perms: perm
		}, cback );
	};

	// METHODS (LIKE, SHARE, ETC...)

	self._parse = function ( dest_div ) 
	{
		if ( dest_div ) 
			dest_div = $ ( dest_div );
		FB.XFBML.parse ( dest_div );
	};

	self._format = function ( type, data )
	{
		var fields = [];
		data.iterate ( function ( value, field )
		{
			if ( value )
				fields.push ( String.formatDict ( social.templates [ 'facebook-data' ], { field: field, value: value } ) );
		} );
		return String.formatDict ( social.templates [ 'facebook-div' ], { type: type, fields: fields.join ( ' ' ) } );
	};

	self.get_like = function ( data )
	{
		return self._format ( 'like', data );
	};

	self.like = function ( dest_div, data )
	{
		$ ( dest_div, self.get_like ( data ) );
	};

	self.get_send = function ( data )
	{
		return self._format ( 'send', data );
	};

	self.send = function ( dest_div, data )
	{
		$ ( dest_div, self.get_send ( data ) );
	};

	self.get_comments = function ( data )
	{
		return self._format ( 'comments', data );
	};

	self.comments = function ( dest_div, data )
	{
		$ ( dest_div, self.get_comments ( data ) );
	};

	// TODO: sistemare usando oauth 2.0

	self.feed = function ( link, name, caption, description )
	{
		FB.ui (
		{
			method: 'feed',
			display: 'popup', // HACK: to avoid conflict with object_enh
			link: link,
			name: name,
			caption: caption,
			description: description
		}, self.cbacks [ 'feed' ] );
	};

	self.share = function ( url )
	{
		FB.ui ( 
		{
			method: 'stream.share',
			display: 'popup', // HACK: to avoid conflict with object_enh
			u: url
		}, self.cbacks [ 'share' ] );
	};

	self.publish = function ( message, name, description )
	{
		FB.ui ( 
		{
			method: 'stream.publish',
			display: 'popup', // HACK: to avoid conflict with object_enh
			message: message,
			attachment:
			{
				name: name,
				description: description
			}
		}, self.cbacks [ 'publish' ] );
	};

	self.post = function ( message, destination )
	{
		if ( ! destination ) destination = 'me';
		self.check_perm ( 'publish_stream', function ()
		{
			self._post ( message, destination );
		} );

	};

	self._post = function ( message, destination )
	{
		FB.api ( '/' + destination + '/feed', 'post', { message: message }, function ( res )
		{
			console.debug ( res );
			if ( res.error )
			{
				console.error ( res.error.message );
			}
			else if ( self.cbacks [ 'post' ] )
				self.cbacks [ 'post' ] ( res );
		} );
	};
} ) ();
